﻿using SuporeSliplampApp.Models;
using SuporeSliplampApp.Util;
using SuporeSliplampApp.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.UI;
using Emgu.CV.Util;
using Color = System.Drawing.Color;
using Point = System.Drawing.Point;
using Rectangle = System.Drawing.Rectangle;
using Size = System.Drawing.Size;
using static SuporeSliplampApp.Util.util;

namespace SuporeSliplampApp.Views
{
    /// <summary>
    /// EditPicControl.xaml 的交互逻辑
    /// </summary>
    public partial class EditPicControl : UserControl
    {
        public  string myPath;
        private DrawingAttributes drawingAttributes;
        Emgu.CV.Image<Bgr, byte> src;
        Mat img1, mask, final;
        double area = 0;
        int imgWid = 0, imgHid = 0;
        public ListControlModel picEditViewModel = new ListControlModel();
        public PicInputModel picInputModel { set; get; } = new PicInputModel();

        public static event EventHandler<ListControlModel> analyseDalegate;
        public EditPicControl(ListControlModel picModel)
        {
            InitializeComponent();
            this.picEditViewModel = picModel;
            this.DataContext = picEditViewModel;
            Unloaded += EditPicControl_Unloaded;
            drawingAttributes = new DrawingAttributes();
            ImgShow.Source = new BitmapImage(new Uri(picEditViewModel.ImgPath));
            imgWid = (int)this.ImgShow.Source.Width;
            imgHid = (int)this.ImgShow.Source.Height;
        }

        private void removeChild()
        {
            DependencyObject obj = VisualTreeHelper.GetParent(this);
            List<Button> btnList = WindowOperator.FindVisualChild<Button>(obj);
            foreach (var item in btnList)
            {
                if (item != null)
                    item.Visibility = Visibility.Visible;
            }
            if (obj is Panel panel)
            {
                if (panel.Children.Contains(this))
                    panel.Children.Remove(this);
            }
        }

        private void EditPicControl_Unloaded(object sender, RoutedEventArgs e)
        {
            //CamaraView.hideOrShowOtherButton();
            
            
        }
        DependencyObject obj = null;
        int index = 0;
        private void CacelBtn_Click(object sender, RoutedEventArgs e)
        {
            removeChild();
        }

        private void ConfirmBtn_Click(object sender, RoutedEventArgs e)
        {
            removeChild();
        }

        private void AnaBtn_Click(object sender, RoutedEventArgs e)
        {
            setCavasEnable();
        }

        private void setCavasEnable()
        {
            if (!ink.IsEnabled)
            {
                ink.IsEnabled = true;
            }
        }

        private void AnylyBtn_Click(object sender, RoutedEventArgs e)
        {
            ImageAnalyse();
        }

        private void ImageAnalyse()
        {
            src = new Image<Bgr, byte>(picEditViewModel.ImgPath);
            img1 = src.Clone().Mat;
            CvInvoke.Resize(img1, img1, new System.Drawing.Size(imgWid, imgHid));
            //CvInvoke.Imshow("img1", img1);
            var list = ink.Strokes;
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            foreach (var item in list)
            {
                VectorOfPoint vectorOfPoint = new VectorOfPoint();
                foreach (var stylusPoint in item.StylusPoints)
                {
                    vectorOfPoint.Push(new System.Drawing.Point[] { new System.Drawing.Point((int)(stylusPoint.X), (int)(stylusPoint.Y)) });
                }
                if (vectorOfPoint.Size <= 0)
                    break;
                contours.Push(vectorOfPoint);
                final = Mat.Zeros(img1.Rows, img1.Cols, DepthType.Cv8U, 3);
                mask = Mat.Zeros(img1.Rows, img1.Cols, DepthType.Cv8U, 1);


                for (int i = 0; i < contours.Size; i++)
                {
                    CvInvoke.DrawContours(mask, contours, i, new MCvScalar(255, 255, 255), -1, LineType.AntiAlias);
                }

                CvInvoke.BitwiseAnd(img1, img1, final, mask);

                int b = bSums(mask);
                Console.WriteLine("白色点数：b=" + b.ToString());
                //CvInvoke.Imshow("final", final);

                Mat img_gray = new Mat();
                Mat result = new Mat();
                Mat clahe_result = new Mat();
                CvInvoke.CvtColor(final, img_gray, ColorConversion.Bgr2Gray);
                //CvInvoke.CvtColor(final, img_gray, ColorConversion.Rgb2Gray);
                //CvInvoke.Imshow("img_gray", img_gray);

                Mat clahe_result2 = new Mat();
                CvInvoke.CLAHE(img_gray, 10, new Size(8, 8), clahe_result2);


                Mat crs = clahe_result2.Clone();
                CvInvoke.CLAHE(clahe_result2, 8, new Size(40, 40), clahe_result2);


                Mat cr = clahe_result2.Clone();
                CvInvoke.Threshold(clahe_result2, clahe_result2, 60, 255, ThresholdType.Otsu);


                Mat se = CvInvoke.GetStructuringElement(0, new Size(3, 3), new Point(-1, -1));
                CvInvoke.Erode(clahe_result2, clahe_result2, se, new Point(-1, -1), 2, BorderType.Default, new MCvScalar());
                CvInvoke.Dilate(clahe_result2, clahe_result2, se, new Point(-1, -1), 3, BorderType.Default, new MCvScalar());



                Mat imBin = new Mat();
                CvInvoke.Threshold(clahe_result2, imBin, 20, 255, ThresholdType.Otsu);


                VectorOfVectorOfPoint contours2 = new VectorOfVectorOfPoint();
                CvInvoke.FindContours(imBin, contours2, null, RetrType.Ccomp, ChainApproxMethod.ChainApproxNone);
                CvInvoke.CvtColor(clahe_result2, clahe_result2, ColorConversion.Gray2Rgb);

                area = CvInvoke.ContourArea(contours2[0], true);

                Mat src1 = img1.Clone();
                CvInvoke.CvtColor(cr, cr, ColorConversion.Gray2Rgb);

                int a = bSums(clahe_result2);
                Console.WriteLine("统计a=" + a.ToString());
                int c = (b - a) * 100 / b;
                Console.WriteLine("缺失率c=" + c.ToString());
                cr.CopyTo(src1);


                Mat mask2 = new Mat();
                CvInvoke.CvtColor(crs, mask2, ColorConversion.Gray2Rgb);
                mask2 = ColorTemprature(mask2, 100);
                CvInvoke.CvtColor(mask2, mask2, ColorConversion.Bgr2Bgra);
                mask2 = SetTransparnt(mask2);
                //CvInvoke.Imshow("mask2", mask2);
                CvInvoke.Imwrite("alpha.png", mask2);
                CvInvoke.DrawContours(mask2, contours2, -1, new MCvScalar(0, 255, 0));

                Mat srcImage1 = img1.Clone();
                CvInvoke.CvtColor(srcImage1, srcImage1, ColorConversion.Bgr2Bgra);
                Mat srcImage2 = mask2.Clone();
                CvInvoke.CvtColor(srcImage2, srcImage2, ColorConversion.Bgr2Bgra);
                Mat imageRoi = new Mat(srcImage1, new Rectangle(0, 0, mask2.Cols, mask2.Rows));
                Mat mask3 = mask2.Clone();

                srcImage2.CopyTo(imageRoi, mask3);                
                CvInvoke.PutText(imageRoi,"缺失率："+c.ToString(),new System.Drawing.Point(10,10),Emgu.CV.CvEnum.FontFace.HersheyPlain,1.5,
                    new MCvScalar(255,255,255));
                //CvInvoke.Imshow("imageRoi", imageRoi);
                //CvInvoke.Imshow("srcImage1", srcImage1);
                //CvInvoke.Imshow("srcImage2", srcImage2);
                string path = Common.comPath +@"\"+ picEditViewModel.Name + "_1.jpg";
                imageRoi.Save(path);
                ListControlModel listControlModel = new ListControlModel();
                listControlModel.ImgPath = path;
                listControlModel.Name = picEditViewModel.Name+"_1";
                analyseDalegate.Invoke(this,listControlModel);
            }
        }

        private void showHandledPic()
        {
            
        }

        Mat SetTransparnt(Mat mat)
        {
            Mat res = new Mat();
            Image<Bgra, byte> src = mat.ToImage<Bgra, byte>();
            for (int i = 0; i < src.Rows; i++)
            {
                for (int j = 0; j < src.Cols; j++)
                {
                    if ((src.Data[i, j, 0] == 0 && src.Data[i, j, 1] == 61 && src.Data[i, j, 2] == 61) || (src.Data[i, j, 0] == 0 && src.Data[i, j, 1] == 60 && src.Data[i, j, 2] == 60))
                    {
                        src.Data[i, j, 0] = 0;
                        src.Data[i, j, 1] = 0;
                        src.Data[i, j, 2] = 0;
                    }
                }
            }
            CvInvoke.CvtColor(src.Mat, src.Mat, ColorConversion.Bgr2Bgra);
            for (int i = 0; i < src.Rows; i++)
            {
                for (int j = 0; j < src.Cols; j++)
                {
                    if ((src.Data[i, j, 0] == 0 && src.Data[i, j, 1] == 0 && src.Data[i, j, 2] == 0))
                    {
                        src.Data[i, j, 3] = 0;
                    }
                }
            }
            return src.Mat;
        }

        int bSums(Mat src)
        {
            Image<Bgr, byte> image = src.ToImage<Bgr, byte>();
            int counter = 0;
            for (int i = 0; i < image.Rows; i++)
            {
                for (int j = 0; j < image.Cols; j++)
                {
                    if ((image.Data[i, j, 0] == 255) && (image.Data[i, j, 0] == 255) && (image.Data[i, j, 0] == 255))
                    {
                        counter++;
                    }
                }
            }
            return counter;
        }
        Mat ColorTemprature(Mat input, int n)
        {
            Image<Bgr, byte> srcImage = input.ToImage<Bgr, byte>();
            Mat tem = input.Clone();
            Image<Bgr, byte> result = tem.ToImage<Bgr, byte>();
            int level = n / 2;
            for (int i = 0; i < srcImage.Rows; ++i)
            {
                //byte* ptr =(byte*)
                for (int j = 0; j < srcImage.Cols; ++j)
                {
                    int R, G, B;
                    R = (int)(srcImage.Data[i, j, 2] + level);
                    G = (int)(srcImage.Data[i, j, 1] + level);
                    B = (int)(srcImage.Data[i, j, 0] - level);
                    if (R > 255)
                        //R = 255;
                        result.Data[i, j, 2] = 255;
                    else if (R < 0)
                        //R = 0;
                        result.Data[i, j, 2] = 0;
                    else
                        result.Data[i, j, 2] = (byte)R;
                    if (G > 255)
                        //G = 255;
                        result.Data[i, j, 1] = 255;
                    else if (G < 0)
                        //G = 0;
                        result.Data[i, j, 1] = 0;
                    else
                        result.Data[i, j, 1] = (byte)G;
                    if (B > 255)
                        //B = 255;
                        result.Data[i, j, 0] = 255;
                    else if (B < 0)
                        // B = 0;
                        result.Data[i, j, 0] = 0;
                    else
                        result.Data[i, j, 0] = (byte)B;
                    //result.Data[i, j, 0] = (byte)B;
                    //result.Data[i, j, 1] = (byte)G;
                    //result.Data[i, j, 2] = (byte)R;
                    tem = result.Mat;


                }
            }
            return tem;
        }
    }
}
